#' @TODO 药物IC50相关分析
#' @title 药物IC50相关分析 
#' @description 利用计算得到的各个药物在样本中的IC50数据，计算相关性，以及组间是否显著差异,生成相关图片.
#' @param Input 包含sample列的矩阵 
#' @param Group_in_Input 用于组间样本秩和检验，包含样本列`sample`，比较`Input`中非sample列数据，在不同样本分组中是否有显著性差异，如果为`NULL`则不进行该分析步骤 
#' @param Df_For_Corr 数据框，包含样本列`sample`，与其他信息，用于计算`Input`中非sample列数据，与`Df_For_Corr`中数据的的spearman相关性，
#' 可以是模型基因表达量或者riskscore等连续变量，如果为`NULL`则不进行该分析步骤 
#' @param saveFile 是否保存文件，默认FALSE 
#' @param od 文件输出路径 
#' @param y_lab_chr 字符串，图中纵坐标轴字段，如果为NULL，默认为log(IC50)
#' @param box_w box图宽
#' @param box_h box图高
#' @param cor_w cor图宽
#' @param cor_h cor图高
#' 
#' @return *list*
#' @export
#' @author *WYK*
#'
BoxCor_Plot <- function(Input = NULL, Group_in_Input = NULL, Df_For_Corr = NULL,
                        saveFile = T, od = "./", Feature_in_Input = NULL, y_lab_chr = NULL,
                        box_w = 3, box_h = 3.5, cor_w = 3.5, cor_h = 3.5) {
    library(tidyverse)
    library(psych)

    if (is.null(y_lab_chr)) {
        y_lab_chr <- "log(IC50)"
    }

    if (!is.null(Group_in_Input)) {
        if (dim(Group_in_Input)[2] > 2) {
            Feaure_name <- Input %>%
                dplyr::select(-sample) %>%
                colnames()
            group_names <- base::setdiff(colnames(Group_in_Input), "sample")

            Wli_res <- map_dfc(group_names, function(group_name) {
                p_val_drug_in_group <- map_dbl(Feaure_name, function(x) {
                    df_tmp <- inner_join(Input %>% dplyr::select(sample, x), Group_in_Input)
                    wilcox_res <- wilcox.test(df_tmp %>% pull(x) ~ get0(group_name), data = df_tmp)
                    return(wilcox_res$p.value)
                })

                p.signif <- cut(p_val_drug_in_group, breaks = c(0, 0.0001, 0.001, 0.01, 0.05, 1), labels = c("****", "***", "**", "*", " "))

                Wli_res <- tibble(
                    "Feaure_name" = Feaure_name,
                    "group" = p_val_drug_in_group,
                    "p.signif" = p.signif
                )

                colnames(Wli_res)[2] <- paste0("WilcoxTsetPval_in_", group_name)
                return(Wli_res)
            })
        } else {
            Feaure_name <- Input %>%
                select(-sample) %>%
                colnames()
            group_name <- base::setdiff(colnames(Group_in_Input), "sample")

            p_val_drug_in_group <- map_dbl(Feaure_name, function(x) {
                df_tmp <- inner_join(Input %>% dplyr::select(sample, x), Group_in_Input)
                wilcox_res <- wilcox.test(df_tmp %>% pull(x) ~ get0(group_name), data = df_tmp)
                return(wilcox_res$p.value)
            })

            p.signif <- cut(p_val_drug_in_group, breaks = c(0, 0.0001, 0.001, 0.01, 0.05, 1), labels = c("****", "***", "**", "*", " "))

            Wli_res <- tibble(
                "Feaure_name" = Feaure_name,
                "group" = p_val_drug_in_group,
                "p.signif" = p.signif
            )

            colnames(Wli_res)[2] <- paste0("WilcoxTsetPval_in_", group_name)
        }
    }

    if (!is.null(Df_For_Corr)) {
        data_for_corr <- inner_join(Input, Df_For_Corr)
        varible_name <- Df_For_Corr %>%
            select(-sample) %>%
            colnames()
        Feaure_name <- Input %>%
            select(-sample) %>%
            colnames()

        x_df <- data_for_corr %>%
            dplyr::select(all_of(Feaure_name)) %>%
            as.matrix()
        y_df <- data_for_corr %>%
            dplyr::select(all_of(varible_name)) %>%
            as.matrix()

        corr_res <- corr.test(x = x_df, y = y_df, method = "spearman", adjust = "BH")
    }

    if (!is.null(Feature_in_Input) & !is.null(Group_in_Input)) {
        N <- length(Feature_in_Input)
        nrow_used <- case_when(
            between(N, 1, 4) ~ 1,
            between(N, 5, 8) ~ 2,
            between(N, 9, 12) ~ 3,
            between(N, 13, 16) ~ 4,
            between(N, 17, 20) ~ 5,
            N >= 21 ~ 6
        )

        width_used <- case_when(
            N < 5 ~ case_when(
                N == 1 ~ box_w * 1,
                N == 2 ~ box_w * 2,
                N == 3 ~ box_w * 3,
                N == 4 ~ box_w * 4
            ),
            N > 4 ~ box_w * 4
        )
        # 根据图片排列行数 判断出图高度
        height_used <- switch(nrow_used,
            box_h,
            box_h * 2,
            box_h * 3,
            box_h * 4,
            box_h * 5,
            box_h * 6
        )

        set.seed(1110)

        group_plot_list <- map(colnames(Group_in_Input %>% select(-sample)), function(x) {
            #  x <- 'riskgroup'
            Group_in_Input_1 <- Group_in_Input %>% dplyr::select("sample", x)

            plot_df <- Input %>%
                dplyr::select("sample", Feature_in_Input) %>%
                inner_join(Group_in_Input_1) %>%
                pivot_longer(col = -c(sample, x), names_to = "Feature_in_Input", values_to = "IC50")

            plot_df$Feature_in_Input <- factor(plot_df$Feature_in_Input, levels = Feature_in_Input)

            group_plot <- plot_df %>%
                ggplot(aes(x = factor(get0(x)), y = IC50)) +
                # geom_boxplot(aes(fill = get0(x)),
                #     color = "black",
                #     width = .5, show.legend = F, outlier.size = .55, alpha = .9, size = .6
                # ) +
                geom_boxplot(aes(), width = .4, show.legend = F, outlier.shape = NA, alpha = 0) +
                geom_jitter(aes(color = get0(x)), width = .2, show.legend = F, alpha = .85) +
                scale_fill_manual(values = RColorBrewer::brewer.pal(9, "Set1")[c(2, 1, 3:9)]) +
                labs(x = x, y = y_lab_chr) +
                theme(legend.position = NULL) +
                egg::theme_article(16) +
                ggpubr::stat_compare_means(label.x.npc = "left", label.y.npc = "top") + # aes(label = ..p.signif..)
                facet_wrap(. ~ Feature_in_Input, scales = "free", nrow = nrow_used)

            return(group_plot)
        })
        names(group_plot_list) <- colnames(Group_in_Input %>% dplyr::select(-sample))
    }

    if (!is.null(Feature_in_Input) & !is.null(Df_For_Corr)) {
        N <- length(Feature_in_Input)
        nrow_used <- case_when(
            between(N, 1, 4) ~ 1,
            between(N, 5, 8) ~ 2,
            between(N, 9, 12) ~ 3,
            between(N, 13, 16) ~ 4,
            between(N, 17, 20) ~ 5,
            N >= 21 ~ 6
        )

        width_used_cor <- case_when(
            N < 5 ~ case_when(
                N == 1 ~ cor_w * 1,
                N == 2 ~ cor_w * 2,
                N == 3 ~ cor_w * 3,
                N == 4 ~ cor_w * 4
            ),
            N > 4 ~ cor_w * 4
        )
        # 根据图片排列行数 判断出图高度
        height_used_cor <- switch(nrow_used,
            cor_h,
            cor_h * 2,
            cor_h * 3,
            cor_h * 4,
            cor_h * 5,
            cor_h * 6
        )

        corPoint_plot_list <- map(colnames(Df_For_Corr %>% dplyr::select(-sample)), function(x) {
            Df_For_Corr_1 <- Df_For_Corr %>%
                dplyr::select("sample", x) %>%
                arrange(get(x))

            single_plot <- map(Feature_in_Input, function(y) {
                corPoint_plot <- Input %>%
                    dplyr::select("sample", y) %>%
                    inner_join(Df_For_Corr_1) %>%
                    pivot_longer(col = -c(sample, x), names_to = "Feature_in_Input", values_to = "IC50") %>%
                    ggplot(aes(x = get0(x), y = IC50)) +
                    geom_point(color = "#377EB8", alpha = .9) +
                    geom_smooth(method = "lm", col = "#E41A1C", alpha = .55) +
                    ggpubr::stat_cor(method = "spearman") +
                    labs(x = x, y = y_lab_chr, title = y) +
                    egg::theme_article(15) +
                    theme(plot.title = element_text(hjust = 0.5))

                return(corPoint_plot)
            })

            names(single_plot) <- str_c(Feature_in_Input, "_in_", x)

            corPoint_plot <- cowplot::plot_grid(plotlist = single_plot, nrow = nrow_used)

            return(corPoint_plot)
        })

        names(corPoint_plot_list) <- colnames(Df_For_Corr %>% dplyr::select(-sample))

        corPoint_SinglePlot_list <- map(colnames(Df_For_Corr %>% dplyr::select(-sample)), function(x) {
            Df_For_Corr_1 <- Df_For_Corr %>%
                dplyr::select("sample", x) %>%
                arrange(get(x))

            single_plot <- map(Feature_in_Input, function(y) {
                corPoint_plot <- Input %>%
                    dplyr::select("sample", y) %>%
                    inner_join(Df_For_Corr_1) %>%
                    pivot_longer(col = -c(sample, x), names_to = "Feature_in_Input", values_to = "IC50") %>%
                    ggplot(aes(x = get0(x), y = IC50)) +
                    geom_point(color = "#377EB8", alpha = .9) +
                    geom_smooth(method = "lm", col = "#E41A1C", alpha = .55) +
                    ggpubr::stat_cor(method = "spearman") +
                    labs(x = x, y = y_lab_chr, title = y) +
                    egg::theme_article(15) +
                    theme(plot.title = element_text(hjust = 0.5))

                return(corPoint_plot)
            })

            names(single_plot) <- str_c(Feature_in_Input, "_in_", x)

            return(single_plot)
        })

        names(corPoint_SinglePlot_list) <- colnames(Df_For_Corr %>% dplyr::select(-sample))
    }

    if (saveFile) {
        if (!dir.exists(str_glue("{od}/Corr_infor/"))) {
            dir.create(str_glue("{od}/Corr_infor/"), recursive = T)
        } else {
            message(str_glue("{od}/Corr_infor/ is ready."))
        }

        if (!is.null(Feature_in_Input) & !is.null(Group_in_Input)) {
            walk(seq_along(group_plot_list), function(x) {
                x <- 1
                plot_chara <- names(group_plot_list)[x]
                ggsave(
                    plot = group_plot_list[[x]], filename = str_glue("{od}/Corr_infor/Figure_{plot_chara}_BoxPlot.pdf"),
                    width = width_used, height = height_used
                )
            })
        }

        if (!is.null(Feature_in_Input) & !is.null(Df_For_Corr)) {
            walk(seq_along(corPoint_plot_list), function(x) {
                # x <- 1
                plot_chara <- names(corPoint_plot_list)[x]
                ggsave(
                    plot = corPoint_plot_list[[x]], filename = str_glue("{od}/Corr_infor/Figure_{plot_chara}_CorPlot.pdf"),
                    width = width_used_cor, height = height_used_cor
                )
            })

            walk(names(corPoint_SinglePlot_list), function(x) {
                # x <- names(corPoint_SinglePlot_list)[1]
                walk(names(corPoint_SinglePlot_list[[x]]), function(y) {
                    # y <- names(corPoint_SinglePlot_list[[x]])[1]
                    ggsave(
                        plot = corPoint_SinglePlot_list[[x]][[y]],
                        filename = str_glue("{od}/Corr_infor/Figure_{y}_CorPlot.pdf"),
                        width = 3.3, height = 3.7
                    )
                })
            })

            # ggsave(
            #     plot = gg.heatmap_res, filename = str_glue("{od}/Corr_infor/Figure_Drug_Heatmap.pdf"),
            #     width = 1.1*length(Feature_in_Input), height = (ncol(Df_For_Corr)-1)+1.5
            # )            
        }

        if (exists("Wli_res")) {
            write_tsv(x = Wli_res, file = str_glue("{od}/Corr_infor/Wli_res_pvalSig_in_Group.txt"))
        }

        if (exists("corr_res")) {
            write_tsv(
                x = corr_res$r %>% as.data.frame() %>% rownames_to_column("Drug"),
                file = str_glue("{od}/Corr_infor/rho.txt")
            )
            write_tsv(
                x = corr_res$p %>% as.data.frame() %>% rownames_to_column("Drug"),
                file = str_glue("{od}/Corr_infor/rho_pval.txt")
            )
        }
    }

    res <- map(c("Wli_res", "corr_res"), function(x) {
        if (exists(x)) {
            return(get0(x))
        } else {
            NA
        }
    })

    names(res) <- c("Wli_res", "corr_res")
    return(res)
}
